/*
 * Created on 2006-8-2 上午06:46:18
 */
package cn.com.sbell.vss.csg.heartbeat;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.mina.common.ExecutorThreadModel;
import org.apache.mina.filter.LoggingFilter;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.transport.socket.nio.SocketAcceptor;
import org.apache.mina.transport.socket.nio.SocketAcceptorConfig;

import cn.com.sbell.vss.csg.vsclient.util.CSGConfiguration;

public class HeartBeatServer {

	private static Log logger = LogFactory.getLog(HeartBeatServer.class);
	private HeartBeatHandler heartBeatHandler;

	private SocketAcceptor acceptor = new SocketAcceptor();

	public void start() throws IOException {
		logger.info("Starting up heartbeat server ... ");
		SocketAcceptorConfig cfg = new SocketAcceptorConfig();
		cfg.setReuseAddress(true);
		ExecutorThreadModel etm = ExecutorThreadModel.getInstance("viss");
		ThreadPoolExecutor threadPool = new ThreadPoolExecutor(CSGConfiguration.MINA_THREADPOOL_MIN, CSGConfiguration.MINA_THREADPOOL_MAX,
															   60, TimeUnit.SECONDS,
															   new LinkedBlockingQueue<Runnable>(CSGConfiguration.MINA_THREADPOOL_WAITQUEUE));
		threadPool.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
		threadPool.setThreadFactory(new ThreadFactory(){

			public Thread newThread(Runnable r) {
				Thread t=new Thread(r);
				t.setDaemon(true);
				return t;
			}
			
		});
		etm.setExecutor(threadPool);
		cfg.setThreadModel(etm);

		acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new HeartBeatProtocolCodecFactory()));
		acceptor.getFilterChain().addLast("logger", new LoggingFilter());
		SocketAddress address = new InetSocketAddress(CSGConfiguration.COMMON_HEARTBEAT_REPORT_PORT);
		acceptor.bind(address, heartBeatHandler, cfg);
		logger.info("Heartbeat server is listening on port " + CSGConfiguration.COMMON_HEARTBEAT_REPORT_PORT);
	}

	public void stop() {
		logger.info("Stopping heartbeat server ... ");
		acceptor.unbindAll();
		logger.info("Stopped heartbeat server successfully!");
	}

	public static void main(String[] args) throws Exception {
		HeartBeatServer server = new HeartBeatServer();
		server.start();
		Thread.sleep(3000);
		server.stop();
	}

	/**
	 * @return the heartBeatHandler
	 */
	public HeartBeatHandler getHeartBeatHandler() {
		return heartBeatHandler;
	}

	/**
	 * @param heartBeatHandler
	 *            the heartBeatHandler to set
	 */
	public void setHeartBeatHandler(HeartBeatHandler heartBeatHandler) {
		this.heartBeatHandler = heartBeatHandler;
	}
}
